package firmwares

import (
	"context"
	"devops-super/api"
	v1 "devops-super/api/product/v1"
	"devops-super/internal/dao"
	"devops-super/internal/model/entity"
	"devops-super/internal/model/mymodel"
	"devops-super/internal/service"
	"errors"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"time"
)

type sFirmware struct{}

var cols = dao.AppFirmware.Columns()

func init() {
	service.RegisterFirmware(New())
}

func New() *sFirmware {
	return &sFirmware{}
}

// Add 添加固件
func (*sFirmware) Add(ctx context.Context, in *entity.AppFirmware) (err error) {
	// 检查固件名称是否重复（同一产品下）
	count, _ := dao.AppFirmware.Ctx(ctx).
		Where(cols.ProductId, in.ProductId).
		Where(cols.Name, in.Name).
		Count()
	if count > 0 {
		return errors.New("固件名称已存在")
	}

	// 检查固件版本是否重复（同一产品下）
	count, _ = dao.AppFirmware.Ctx(ctx).
		Where(cols.ProductId, in.ProductId).
		Where(cols.Version, in.Version).
		Count()
	if count > 0 {
		return errors.New("固件版本已存在")
	}

	_, err = dao.AppFirmware.Ctx(ctx).Insert(in)
	return
}

// Upt 更新固件
func (*sFirmware) Upt(ctx context.Context, in *entity.AppFirmware) (err error) {
	// 检查固件名称是否重复（同一产品下，排除自身）
	count, _ := dao.AppFirmware.Ctx(ctx).
		Where(cols.ProductId, in.ProductId).
		Where(cols.Name, in.Name).
		Where(cols.Id, "!=", in.Id).
		Count()
	if count > 0 {
		return errors.New("固件名称已存在")
	}

	// 检查固件版本是否重复（同一产品下，排除自身）
	count, _ = dao.AppFirmware.Ctx(ctx).
		Where(cols.ProductId, in.ProductId).
		Where(cols.Version, in.Version).
		Where(cols.Id, "!=", in.Id).
		Count()
	if count > 0 {
		return errors.New("固件版本已存在")
	}

	_, err = dao.AppFirmware.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
	return
}

// GetPageLst 分页获取固件列表
func (*sFirmware) GetPageLst(ctx context.Context, in *v1.GetFirmwarePageLstReq) (out *api.PageLstRes[*mymodel.AppFirmwareResponse], err error) {
	out = &api.PageLstRes[*mymodel.AppFirmwareResponse]{}
	m := dao.AppFirmware.Ctx(ctx).Safe(true)

	if in.Name != "" {
		m = m.Where(cols.Name+" like ? ", "%"+in.Name+"%")
	}
	if in.Version != "" {
		m = m.Where(cols.Version+" like ? ", "%"+in.Version+"%")
	}
	if in.ProductId > 0 {
		m = m.Where(cols.ProductId, in.ProductId)
	}
	// 按时间范围筛选
	if in.TimeRange != nil {
		if len(in.TimeRange) != 2 {
			return nil, gerror.NewCode(gcode.CodeInvalidParameter, "时间范围参数格式错误")
		}
		// 新增时间转换逻辑
		startTime, err := time.Parse(time.RFC3339, in.TimeRange[0])
		if err != nil {
			return nil, gerror.WrapCode(gcode.CodeInvalidParameter, err, "开始时间格式错误")
		}
		endTime, err := time.Parse(time.RFC3339, in.TimeRange[1])
		if err != nil {
			return nil, gerror.WrapCode(gcode.CodeInvalidParameter, err, "结束时间格式错误")
		}
		timeLayout := "2006-01-02 15:04:05"
		timeStr0 := startTime.Local().Format(timeLayout)
		timeStr1 := endTime.Local().Format(timeLayout)
		m = m.WhereBetween(dao.AppDeviceGroup.Columns().CreatedAt, timeStr0, timeStr1)
	}

	// 分页查询获取实体数据
	var entities []*entity.AppFirmware
	count, err := m.Count()
	if err != nil {
		return nil, err
	}
	out.Total = count

	if count > 0 {
		if err = m.Offset(in.Offset()).Limit(in.Limit()).Scan(&entities); err != nil {
			return nil, err
		}

		// 转换为响应模型
		out.List = make([]*mymodel.AppFirmwareResponse, len(entities))

		// 收集所有产品ID
		var productIds []int64
		for _, e := range entities {
			if e.ProductId > 0 {
				productIds = append(productIds, e.ProductId)
			}
		}

		// 批量查询产品信息建立映射
		productMap := make(map[int64]string)
		if len(productIds) > 0 {
			var products []*entity.AppProduct
			if err := dao.AppProduct.Ctx(ctx).Where("id IN (?)", productIds).Scan(&products); err != nil {
				return nil, err
			}
			for _, p := range products {
				productMap[int64(p.Id)] = p.Name
			}
		}

		// 赋值响应数据并拼接产品名称
		for i, e := range entities {
			out.List[i] = &mymodel.AppFirmwareResponse{
				Id:          e.Id,
				Name:        e.Name,
				ProductId:   e.ProductId,
				ProductName: productMap[e.ProductId],
				Version:     e.Version,
				Part:        e.Part,
				Remark:      e.Remark,
				FileMd5:     e.FileMd5,
				FileUrl:     e.FileUrl,
				CreatedAt:   e.CreatedAt,
				UpdatedAt:   e.UpdatedAt,
				WhereAt:     e.WhereAt,
				AppFileId:   e.AppFileId,
				Image:       e.Image,
			}
		}
	}

	return
}

// Del 删除固件
func (*sFirmware) Del(ctx context.Context, id int) (err error) {
	// 实际项目中可能需要检查固件是否被使用
	// 例如：检查是否有设备正在使用该固件

	_, err = dao.AppFirmware.Ctx(ctx).WherePri(id).Delete()
	return
}

func (*sFirmware) GetOne(ctx context.Context, id int) (out *entity.AppFirmware, err error) {
	out = &entity.AppFirmware{}
	err = dao.AppFirmware.Ctx(ctx).WherePri(id).Scan(&out)
	return
}

func (*sFirmware) GetOptions(ctx context.Context, in *v1.GetFirmwareOptionsReq) (out *v1.GetFirmwareOptionsRes, err error) {
	m := dao.AppFirmware.Ctx(ctx)

	// 按产品筛选
	if in.ProductId > 0 {
		m = m.Where(cols.ProductId, in.ProductId)
	}

	var data []*entity.AppFirmware
	m.Scan(&data)
	out = new(v1.GetFirmwareOptionsRes)
	out.Options = make([]*api.FormOptionsItem, 0)
	for _, v := range data {
		out.Options = append(out.Options, &api.FormOptionsItem{
			Value: v.Id,
			Label: v.Name + "(v" + v.Version + ")",
		})
	}
	return
}
